﻿using Microsoft.EntityFrameworkCore.Storage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace HiCore.Extensions.UnitOfWork.EntityFramework
{
    /// <summary>
    /// EFCore批量操作扩展
    /// </summary>
    public static class BatchExtentions
    {
        /// <summary>
        /// 递归解析表达式 
        /// </summary>
        /// <param name="tableAlias"></param>
        /// <param name="expression"></param>
        /// <param name="sb"></param>
        /// <param name="sp"></param>
        public static void CreateUpdateBody(string tableAlias, Expression expression, ref StringBuilder sb, ref Dictionary<string, object> sp)
        {
            if (expression is BinaryExpression binaryExpression)
            {
                CreateUpdateBody(tableAlias, binaryExpression.Left, ref sb, ref sp);

                switch (binaryExpression.NodeType)
                {
                    case ExpressionType.Add:
                        sb.Append(" +");
                        break;
                    case ExpressionType.Divide:
                        sb.Append(" /");
                        break;
                    case ExpressionType.Multiply:
                        sb.Append(" *");
                        break;
                    case ExpressionType.Subtract:
                        sb.Append(" -");
                        break;
                    case ExpressionType.And:
                        sb.Append(" ,");
                        break;
                    case ExpressionType.AndAlso:
                        sb.Append(" ,");
                        break;
                    case ExpressionType.Or:
                        sb.Append(" ,");
                        break;
                    case ExpressionType.OrElse:
                        sb.Append(" ,");
                        break;
                    case ExpressionType.Equal:
                        sb.Append(" =");
                        break;
                    default: break;
                }

                CreateUpdateBody(tableAlias, binaryExpression.Right, ref sb, ref sp);
            }

            if (expression is ConstantExpression constantExpression)
            {
                var parmName = $"param_{sp.Count}";
                sp.Add(parmName, constantExpression.Value);
                sb.Append($" @{parmName}");
            }

            if (expression is MemberExpression memberExpression)
            {
                //sb.Append($"[{tableAlias}].[{memberExpression.Member.Name}]");
                sb.Append($"{tableAlias}.{memberExpression.Member.Name}");
            }
        }
    }
}
